package com.xyht.sca_s.student_manage_system.modules.student_difficulty.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ExceptionCast;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.CacheUtil;
import com.xyht.sca_s.student_manage_system.modules.student.entity.SmsStudentInfo;
import com.xyht.sca_s.student_manage_system.modules.student.mapper.SmsStudentInfoMapper;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.entity.SmsStudentDifficultyApply;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.entity.SmsStudentDifficultyFamilyRelation;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.entity.SmsStudentDifficultyInfoType;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.entity.SmsStudentDifficultyTask;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.entity.req.SmsStudentDifficultyApplyReq;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.entity.req.SmsStudentDifficultyFamilyRelationReq;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.entity.resp.SmsStudentDifficultyApplyResp;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.entity.resp.SmsStudentDifficultyFamilyRelationResp;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.entity.resp.SmsStudentDifficultyTaskApplyResp;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.entity.resp.SmsStudentDifficultyTaskResp;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.mapper.SmsStudentDifficultyApplyMapper;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.mapper.SmsStudentDifficultyFamilyRelationMapper;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.mapper.SmsStudentDifficultyTaskMapper;
import com.xyht.sca_s.student_manage_system.modules.student_difficulty.service.SmsStudentDifficultyApplyService;
import com.xyht.sca_s.student_manage_system.modules.tips.utils.TipsUtil;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.student_difficulty.constant.ApplyStatusConstant.APPLY_STATUS_REJECT;
import static com.xyht.sca_s.student_manage_system.modules.student_difficulty.constant.CloseFlagConstant.IS_CLOSE_FALSE;
import static com.xyht.sca_s.student_manage_system.modules.student_difficulty.constant.CloseFlagConstant.IS_CLOSE_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.student_difficulty.constant.TaskRangeFlagConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.AppNameConstant.APP_BACK_DIFFICULTY;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.AppNameConstant.APP_WEB_DIFFICULTY;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.CommonConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.RangeTypeConstant.RANGE_TYPE_PERSON;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.TipsTypeConstant.TIPS_TYPE_MESSAGE;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.UserTypeConstant.USER_TYPE_STUDENT;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.UserTypeConstant.USER_TYPE_TEACHER;

/**
 * <p>
 * 家庭经济困难认定申请表 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-03-01
 */
@Service
public class SmsStudentDifficultyApplyServiceImpl extends ServiceImpl<SmsStudentDifficultyApplyMapper, SmsStudentDifficultyApply> implements SmsStudentDifficultyApplyService {
    @Autowired
    private SmsStudentDifficultyApplyMapper smsStudentDifficultyApplyMapper;
    @Autowired
    private SmsStudentDifficultyFamilyRelationMapper smsStudentDifficultyFamilyRelationMapper;
    @Autowired
    private SmsStudentDifficultyTaskMapper smsStudentDifficultyTaskMapper;
    @Autowired
    private TipsUtil tipsUtil;
    @Autowired
    private CacheUtil cacheUtil;
    @Autowired
    private SmsStudentDifficultyApplyMapper smsDifficultyApplyMapper;
    @Autowired
    FreeMarkerConfigurer freeMarkerConfigurer;
    @Autowired
    private SmsStudentInfoMapper smsStudentInfoMapper;

    @Override
    @Transactional
    public ResponseResult submitDifficultyApply(SmsStudentDifficultyApplyReq applyReq, String user_id) {
        if (isNullOrEmpty(applyReq.getTaskId()) || isNullOrEmpty(applyReq.getStuName())
                || isNullOrEmpty(applyReq.getStuNo()) || isNullOrEmpty(applyReq.getStuTel())
                || isNullOrEmpty(applyReq.getStuIdCard()) || isNullOrEmpty(applyReq.getStuSex())
                || isNullOrEmpty(applyReq.getStuBirth())
//                || isNullOrEmpty(applyReq.getStuCollege())
//                || isNullOrEmpty(applyReq.getStuMajor()) || isNullOrEmpty(applyReq.getStuGrade())
//                || isNullOrEmpty(applyReq.getStuClass())
                || isNullOrEmpty(applyReq.getFamilyNum())
                || isNullOrEmpty(applyReq.getPostalCode()) || isNullOrEmpty(applyReq.getStuNativePlace())
                || isNullOrEmpty(applyReq.getAccountNature()) || isNullOrEmpty(applyReq.getParentTel())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        if (applyReq.getSpecialGroupType() == null || applyReq.getDifficultyInfoType() == null) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsStudentDifficultyTask task = smsStudentDifficultyTaskMapper.selectById(applyReq.getTaskId());
        if (task == null || task.getId() == null) {
            return CommonResult.failed(CommonCodeEnum.DIFFICULTY_NOT_EXIST);
        }

        //检查本人提交，避免重复提交
        List<SmsStudentDifficultyApply> applyList = smsStudentDifficultyApplyMapper.selectList(new QueryWrapper<SmsStudentDifficultyApply>()
                .lambda()
                .eq(SmsStudentDifficultyApply::getTaskId, applyReq.getTaskId())
                .eq(SmsStudentDifficultyApply::getUserId, user_id));
        if (applyList != null && applyList.size() > 0) {
            return CommonResult.failed(CommonCodeEnum.DIFFICULTY_APPLY_EXIST);
        }

        if (applyReq.getFamilyList() == null || applyReq.getFamilyList().size() < 1) {
            return CommonResult.failed(CommonCodeEnum.DIFFICULTY_INVALID_FAMILY);
        }

        SmsStudentDifficultyApply smsStudentDifficultyApply = new SmsStudentDifficultyApply();
        BeanUtils.copyProperties(applyReq, smsStudentDifficultyApply);
        smsStudentDifficultyApply.setUserId(user_id);
        smsStudentDifficultyApply.setSpecialGroupType(JSONObject.toJSONString(applyReq.getSpecialGroupType()));
        smsStudentDifficultyApply.setDifficultyInfoType(JSONObject.toJSONString(applyReq.getDifficultyInfoType()));

        smsStudentDifficultyApplyMapper.insert(smsStudentDifficultyApply);

        String apply_id = smsStudentDifficultyApply.getId();
        if (isNullOrEmpty(apply_id)) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
        }

        for (SmsStudentDifficultyFamilyRelationReq relationReq : applyReq.getFamilyList()) {
            if (isNullOrEmpty(relationReq.getAge()) || isNullOrEmpty(relationReq.getName())
                    || isNullOrEmpty(relationReq.getRelation()) || isNullOrEmpty(relationReq.getWorkAddr())
                    || isNullOrEmpty(relationReq.getJob()) || isNullOrEmpty(relationReq.getAnnualIncome())
                    || isNullOrEmpty(relationReq.getHealthStatus())) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.SUBSIDIES_NOT_COMPLETE_FAMILY));
            }
            SmsStudentDifficultyFamilyRelation familyRelation = new SmsStudentDifficultyFamilyRelation();
            BeanUtils.copyProperties(relationReq, familyRelation);

            familyRelation.setApplyId(apply_id);
            smsStudentDifficultyFamilyRelationMapper.insert(familyRelation);
        }

        //完成消息待办
        tipsUtil.finishTips(applyReq.getTaskId(), user_id, null);

        //创建消息
        List<String> personList = new ArrayList<>();
        personList.add(task.getUserId());
        tipsUtil.addTips(TIPS_DIFFICULTY_TITLE_MESSAGE,
                TIPS_DIFFICULTY_TEACHER_DESCRIPTION_MESSAGE, //TIPS_LEAVE_DESCRIPTION_MESSAGE
                TIPS_TYPE_MESSAGE,
                APP_BACK_DIFFICULTY,
                RANGE_TYPE_PERSON, //RANGE_TYPE_ROLE
                personList.toString(),
                smsStudentDifficultyApply.getId(),
                USER_TYPE_TEACHER,
                null
        );

        return CommonResult.success();
    }

    @Override
    @Transactional
    public ResponseResult submitDifficultyRejectApply(SmsStudentDifficultyApplyReq applyReq, String user_id) {
        if (isNullOrEmpty(applyReq.getTaskId()) || isNullOrEmpty(applyReq.getStuName())
                || isNullOrEmpty(applyReq.getStuNo()) || isNullOrEmpty(applyReq.getStuTel())
                || isNullOrEmpty(applyReq.getStuIdCard()) || isNullOrEmpty(applyReq.getStuSex())
                || isNullOrEmpty(applyReq.getStuBirth())
//                || isNullOrEmpty(applyReq.getStuCollege())
//                || isNullOrEmpty(applyReq.getStuMajor()) || isNullOrEmpty(applyReq.getStuGrade())
//                || isNullOrEmpty(applyReq.getStuClass())
                || isNullOrEmpty(applyReq.getFamilyNum())
                || isNullOrEmpty(applyReq.getPostalCode()) || isNullOrEmpty(applyReq.getId())
                || isNullOrEmpty(applyReq.getStuNativePlace())
                || isNullOrEmpty(applyReq.getAccountNature()) || isNullOrEmpty(applyReq.getParentTel())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        if (applyReq.getSpecialGroupType() == null || applyReq.getDifficultyInfoType() == null) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        if (applyReq.getFamilyList() == null || applyReq.getFamilyList().size() < 1) {
            return CommonResult.failed(CommonCodeEnum.DIFFICULTY_INVALID_FAMILY);
        }

        SmsStudentDifficultyApply DifficultyApply = smsStudentDifficultyApplyMapper.selectById(applyReq.getId());
        if (DifficultyApply == null || DifficultyApply.getId() == null) {
            return CommonResult.failed(CommonCodeEnum.DIFFICULTY_APPLY_NOT_EXIST);
        }

        SmsStudentDifficultyApply smsStudentDifficultyApply = new SmsStudentDifficultyApply();
        BeanUtils.copyProperties(applyReq, smsStudentDifficultyApply);

        smsStudentDifficultyApplyMapper.updateById(smsStudentDifficultyApply);

        smsStudentDifficultyFamilyRelationMapper.delete(new QueryWrapper<SmsStudentDifficultyFamilyRelation>()
                .lambda().eq(SmsStudentDifficultyFamilyRelation::getApplyId, applyReq.getId()));

        String apply_id = smsStudentDifficultyApply.getId();
        if (isNullOrEmpty(apply_id)) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
        }

        for (SmsStudentDifficultyFamilyRelationReq relationReq : applyReq.getFamilyList()) {
            if (isNullOrEmpty(relationReq.getAge()) || isNullOrEmpty(relationReq.getName())
                    || isNullOrEmpty(relationReq.getRelation()) || isNullOrEmpty(relationReq.getWorkAddr())
                    || isNullOrEmpty(relationReq.getJob()) || isNullOrEmpty(relationReq.getAnnualIncome())
                    || isNullOrEmpty(relationReq.getHealthStatus())) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.SUBSIDIES_NOT_COMPLETE_FAMILY));
            }
            SmsStudentDifficultyFamilyRelation familyRelation = new SmsStudentDifficultyFamilyRelation();
            BeanUtils.copyProperties(relationReq, familyRelation);

            familyRelation.setApplyId(apply_id);
            smsStudentDifficultyFamilyRelationMapper.insert(familyRelation);
        }

        //完成消息待办
        tipsUtil.finishTips(apply_id, user_id, IS_CLOSE_TRUE);
        return CommonResult.success();
    }

    @Override
    public ResponseResult rejectDifficultyApply(SmsStudentDifficultyApplyReq applyReq) {
        if (isNullOrEmpty(applyReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsStudentDifficultyApply DifficultyApply = smsStudentDifficultyApplyMapper.selectById(applyReq.getId());
        if (DifficultyApply == null || DifficultyApply.getId() == null) {
            return CommonResult.failed(CommonCodeEnum.DIFFICULTY_APPLY_NOT_EXIST);
        }

        DifficultyApply.setApplyStatus(APPLY_STATUS_REJECT);
        DifficultyApply.setRejectInfo(applyReq.getRejectInfo());
        smsStudentDifficultyApplyMapper.updateById(DifficultyApply);

        //创建消息
        List<String> personList = new ArrayList<>();
        personList.add(DifficultyApply.getUserId());
        tipsUtil.addTips(TIPS_DIFFICULTY_TITLE_MESSAGE,
                TIPS_DIFFICULTY_DESCRIPTION_MESSAGE, //TIPS_LEAVE_DESCRIPTION_MESSAGE
                TIPS_TYPE_MESSAGE,
                APP_WEB_DIFFICULTY,
                RANGE_TYPE_PERSON, //RANGE_TYPE_ROLE
                personList.toString(),
                DifficultyApply.getId(),
                USER_TYPE_STUDENT,
                null
        );
        return CommonResult.success();
    }

    @Override
    public ResponseResult getOwnDifficultyTaskList(Integer pageNum, Integer pageSize, String user_id, String search_str) {
        List<SmsStudentDifficultyApply> applyList = smsStudentDifficultyApplyMapper.selectList(new QueryWrapper<SmsStudentDifficultyApply>()
                .lambda()
                .eq(SmsStudentDifficultyApply::getUserId, user_id));
        List<String> filledTaskList = applyList.stream().map(SmsStudentDifficultyApply::getTaskId).collect(Collectors.toList());

        QueryWrapper<SmsStudentDifficultyTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SmsStudentDifficultyTask::getIsClose, IS_CLOSE_FALSE)
                .and(lambdaQuery -> lambdaQuery
                        .isNull(SmsStudentDifficultyTask::getExpirationTime)
                        .or()
                        .gt(SmsStudentDifficultyTask::getExpirationTime, new Date())
                )
                .orderByDesc(SmsStudentDifficultyTask::getCreateTime);
        if (filledTaskList.size() > 0) {
            queryWrapper.lambda().notIn(SmsStudentDifficultyTask::getId, filledTaskList);
        }

        List<SmsStudentDifficultyTask> taskList = smsStudentDifficultyTaskMapper.selectList(queryWrapper);
        List<String> resultTaskIDList = taskList.stream().filter(task -> {
            List<String> rangeList = JSONObject.parseArray(task.getRangeId(), String.class);
            if (task.getTaskRange() != TASK_RANGE_ALL && (rangeList == null || rangeList.size() < 1)) {
                return false;
            }
            boolean flag = false;
            switch (task.getTaskRange()) {
                case TASK_RANGE_ALL:
                    flag = true;
                    break;
                case TASK_RANGE_ORG:
                    List<String> orgList = cacheUtil.getOrgList(user_id);
                    if (orgList != null && orgList.size() > 0) {
                        List<String> resultList = (List<String>) CollectionUtils.intersection(orgList, rangeList);
                        if (resultList.size() > 0) {
                            flag = true;
                        }
                    }
                    break;
                case TASK_RANGE_ROLE:
                    List<String> roleList = cacheUtil.getRoleList(user_id);
                    if (roleList != null && roleList.size() > 0) {
                        List<String> resultList = (List<String>) CollectionUtils.intersection(roleList, rangeList);
                        if (resultList.size() > 0) {
                            flag = true;
                        }
                    }
                    break;
                case TASK_RANGE_PERSON:
                    List<String> resultList = rangeList.stream().filter(person -> person.equals(user_id)).collect(Collectors.toList());
                    if (resultList.size() > 0) {
                        flag = true;
                    }
                    break;
            }
            return flag;
        }).map(SmsStudentDifficultyTask::getId).collect(Collectors.toList());


        List<SmsStudentDifficultyTaskResp> taskRespList = new ArrayList<>();
        int total = 0;
        if (resultTaskIDList.size() > 0) {
            Page<SmsStudentDifficultyTask> page = new Page<>(pageNum, pageSize);
            QueryWrapper<SmsStudentDifficultyTask> taskQueryWrapper = new QueryWrapper<>();
            if (!isNullOrEmpty(search_str)) {
                taskQueryWrapper.lambda().eq(SmsStudentDifficultyTask::getTaskName, search_str);
            }
            taskQueryWrapper.lambda().in(SmsStudentDifficultyTask::getId, resultTaskIDList);
            smsStudentDifficultyTaskMapper.selectPage(page, taskQueryWrapper);
            taskRespList = page.getRecords().stream().map(task -> {
                SmsStudentDifficultyTaskResp smsStudentDifficultyTaskResp = new SmsStudentDifficultyTaskResp();
                BeanUtils.copyProperties(task, smsStudentDifficultyTaskResp);
                return smsStudentDifficultyTaskResp;
            }).collect(Collectors.toList());
            total = (int) page.getTotal();
        }
        return CommonResult.success(taskRespList, total);
    }

    @Override
    public ResponseResult getSubmitDifficultyApply(String task_id, String user_id) {
        SmsStudentDifficultyApplyResp applyResp = new SmsStudentDifficultyApplyResp();

        SmsStudentDifficultyTask task = smsStudentDifficultyTaskMapper.selectById(task_id);
        if (task == null || task.getId() == null) {
            return CommonResult.failed(CommonCodeEnum.DIFFICULTY_NOT_EXIST);
        }

        List<SmsStudentDifficultyApply> list = smsStudentDifficultyApplyMapper.selectList(new QueryWrapper<SmsStudentDifficultyApply>()
                .lambda()
                .eq(SmsStudentDifficultyApply::getTaskId, task_id)
                .eq(SmsStudentDifficultyApply::getUserId, user_id));
        if (list != null && list.size() > 0) {
            return CommonResult.failed(CommonCodeEnum.DIFFICULTY_APPLY_EXIST);
        }

        SmsUser user = cacheUtil.getUserInfo(user_id);
        List<SmsStudentInfo> stuList = smsStudentInfoMapper.selectList(new QueryWrapper<SmsStudentInfo>()
                .lambda()
                .eq(SmsStudentInfo::getStuNo, user.getUsername()));
        if (stuList != null && stuList.size() > 0) {
            SmsStudentInfo smsDifficultyApply = stuList.get(0);
            BeanUtils.copyProperties(smsDifficultyApply, applyResp);
            applyResp.setId(null);
        }
        applyResp.setTaskId(task_id);
        return CommonResult.success(applyResp);
    }

    @Override
    public ResponseResult getDifficultyApplyHistory(Integer pageNum, Integer pageSize, String user_id, String search_str) {
        List<SmsStudentDifficultyApply> applyList = smsStudentDifficultyApplyMapper.selectList(new QueryWrapper<SmsStudentDifficultyApply>()
                .lambda()
                .eq(SmsStudentDifficultyApply::getUserId, user_id));
        List<String> taskIDList = applyList.stream().map(SmsStudentDifficultyApply::getTaskId).collect(Collectors.toList());

        List<SmsStudentDifficultyTaskApplyResp> taskRespList = new ArrayList<>();
        int total = 0;
        if (taskIDList.size() > 0) {
            Page<SmsStudentDifficultyTask> page = new Page<>(pageNum, pageSize);
            QueryWrapper<SmsStudentDifficultyTask> taskQueryWrapper = new QueryWrapper<>();
            if (!isNullOrEmpty(search_str)) {
                taskQueryWrapper.lambda().eq(SmsStudentDifficultyTask::getTaskName, search_str);
            }
            taskQueryWrapper.lambda()
                    .in(SmsStudentDifficultyTask::getId, taskIDList)
                    .orderByDesc(SmsStudentDifficultyTask::getCreateTime);
            smsStudentDifficultyTaskMapper.selectPage(page, taskQueryWrapper);
            taskRespList = page.getRecords().stream().map(task -> {
                SmsStudentDifficultyTaskApplyResp smsStudentDifficultyTaskResp = new SmsStudentDifficultyTaskApplyResp();
                BeanUtils.copyProperties(task, smsStudentDifficultyTaskResp);

                List<SmsStudentDifficultyApply> filterApply = applyList.stream()
                        .filter(apply -> apply.getTaskId().equals(task.getId()))
                        .collect(Collectors.toList());
                smsStudentDifficultyTaskResp.setApplyStatus(filterApply.get(0).getApplyStatus());
                smsStudentDifficultyTaskResp.setApply_id(filterApply.get(0).getId());
                smsStudentDifficultyTaskResp.setRejectInfo(filterApply.get(0).getRejectInfo());
                return smsStudentDifficultyTaskResp;
            }).collect(Collectors.toList());
            total = (int) page.getTotal();

        }
        return CommonResult.success(taskRespList, total);
    }

    @Override
    public ResponseResult getDifficultyApplyDetail(String apply_id) {
        if (isNullOrEmpty(apply_id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsStudentDifficultyApply difficultyApply = smsStudentDifficultyApplyMapper.selectById(apply_id);
        if (difficultyApply == null || difficultyApply.getId() == null) {
            return CommonResult.failed(CommonCodeEnum.DIFFICULTY_APPLY_NOT_EXIST);
        }

        SmsStudentDifficultyApplyResp applyResp = new SmsStudentDifficultyApplyResp();
        BeanUtils.copyProperties(difficultyApply, applyResp);

        List<SmsStudentDifficultyFamilyRelationResp> familyRespList = smsStudentDifficultyFamilyRelationMapper
                .selectList(new QueryWrapper<SmsStudentDifficultyFamilyRelation>()
                        .lambda()
                        .eq(SmsStudentDifficultyFamilyRelation::getApplyId, applyResp.getId()))
                .stream()
                .map(familyRelation -> {
                    SmsStudentDifficultyFamilyRelationResp familyRelationResp = new SmsStudentDifficultyFamilyRelationResp();
                    BeanUtils.copyProperties(familyRelation, familyRelationResp);
                    return familyRelationResp;
                })
                .collect(Collectors.toList());
        applyResp.setFamilyList(familyRespList);

        String specialGroupType = difficultyApply.getSpecialGroupType();
        String difficultyInfoType = difficultyApply.getDifficultyInfoType();
        List<Integer> specialGroupTypeList = new ArrayList<>();
        List<SmsStudentDifficultyInfoType> difficultyInfoTypeList = new ArrayList<>();
        if (!isNullOrEmpty(specialGroupType)) {
            specialGroupTypeList = JSONObject.parseArray(specialGroupType, Integer.class);
        }
        if (!isNullOrEmpty(difficultyInfoType)) {
            difficultyInfoTypeList = JSONObject.parseArray(difficultyInfoType, SmsStudentDifficultyInfoType.class);
        }
        applyResp.setSpecialGroupType(specialGroupTypeList);
        applyResp.setDifficultyInfoType(difficultyInfoTypeList);
        return CommonResult.success(applyResp);
    }

    @Override
    public ResponseResult exportDifficultyApply(String apply_id, HttpServletResponse response) {
        try {
            SmsStudentDifficultyApply difficultyApply = smsStudentDifficultyApplyMapper.selectById(apply_id);
            if (difficultyApply == null || difficultyApply.getId() == null) {
                return CommonResult.failed(CommonCodeEnum.DIFFICULTY_APPLY_NOT_EXIST);
            }

            List<SmsStudentDifficultyFamilyRelation> familyRelationList = smsStudentDifficultyFamilyRelationMapper.selectList(new QueryWrapper<SmsStudentDifficultyFamilyRelation>()
                    .lambda()
                    .eq(SmsStudentDifficultyFamilyRelation::getApplyId, apply_id));


            Map<String, Object> dataMap = new HashMap<>();
            //基础信息替换
            dataMap.put("stuName", getParamValue(difficultyApply.getStuName()));
            dataMap.put("stuSex", getParamValue(difficultyApply.getStuSex()));
            dataMap.put("stuBirth", getParamValue(difficultyApply.getStuBirth()));
            dataMap.put("stuNativePlace", getParamValue(difficultyApply.getStuNativePlace()));
            dataMap.put("stuNo", getParamValue(difficultyApply.getStuNo()));
            dataMap.put("stuIdCard", getParamValue(difficultyApply.getStuIdCard()));
            dataMap.put("stuTel", getParamValue(difficultyApply.getStuTel()));
            dataMap.put("familyNum", getParamValue(difficultyApply.getFamilyNum()));
            dataMap.put("stuCollege", getParamValue(difficultyApply.getStuCollege()));
            dataMap.put("stuMajor", getParamValue(difficultyApply.getStuMajor()));
            dataMap.put("stuGrade", getParamValue(difficultyApply.getStuGrade()));
            dataMap.put("stuClass", getParamValue(difficultyApply.getStuClass()));
            dataMap.put("parentTel", getParamValue(difficultyApply.getParentTel()));
            dataMap.put("schoolFee", getParamValue(difficultyApply.getSchoolFee()));
            dataMap.put("dormitoryFee", getParamValue(difficultyApply.getDormitoryFee()));
            dataMap.put("detailAddr", getParamValue(difficultyApply.getDetailAddr()));
            dataMap.put("postalCode", getParamValue(difficultyApply.getPostalCode()));
            if (difficultyApply.getAccountNature() == 1) {
                dataMap.put("accountNature0", "□"); //☑
                dataMap.put("accountNature1", "☑");
            } else if (difficultyApply.getAccountNature() == 0) {
                dataMap.put("accountNature0", "☑"); //☑
                dataMap.put("accountNature1", "□");
            } else {
                dataMap.put("accountNature0", "□"); //☑
                dataMap.put("accountNature1", "□");
            }

            //特殊群体类型
            List<Integer> specialGroupTypeList = JSONObject.parseArray(difficultyApply.getSpecialGroupType(), Integer.class);
            for (int i = 1; i < 7; i++) {
                if (specialGroupTypeList != null && specialGroupTypeList.size() > 0) {
                    int finalI = i;
                    List<Integer> filterSGT = specialGroupTypeList.stream().filter(sp -> sp.equals(finalI)).collect(Collectors.toList());
                    if (filterSGT.size() > 0) {
                        dataMap.put("specialGroupType" + i, "☑");
                        continue;
                    }
                }
                dataMap.put("specialGroupType" + i, "□");
            }

            //影响家庭经济状况其他信息
            List<SmsStudentDifficultyInfoType> studentDifficultyInfoTypeList = JSONObject.parseArray(difficultyApply.getDifficultyInfoType(), SmsStudentDifficultyInfoType.class);
            for (int j = 1; j < 8; j++) {
                if (studentDifficultyInfoTypeList != null && studentDifficultyInfoTypeList.size() > 0) {
                    int finalI = j;
                    List<SmsStudentDifficultyInfoType> filterSSDIT = studentDifficultyInfoTypeList.stream().filter(sp -> sp.getIndex().equals(finalI)).collect(Collectors.toList());
                    if (filterSSDIT.size() > 0) {
                        dataMap.put("difficultyInfoType" + j, "☑");
                        dataMap.put("difficultyInfoContent" + j, getParamValue(filterSSDIT.get(0).getContent()));
                        continue;
                    }
                }
                dataMap.put("difficultyInfoType" + j, "□");
                dataMap.put("difficultyInfoContent" + j, "");
            }

            //家庭信息替换
            int count = 1;
            if (familyRelationList != null && familyRelationList.size() > 0) {
                for (SmsStudentDifficultyFamilyRelation family : familyRelationList) {
                    dataMap.put("name" + count, family.getName() == null ? "" : family.getName());
                    dataMap.put("age" + count, family.getAge() == null ? "" : family.getAge());
                    dataMap.put("relation" + count, family.getRelation() == null ? "" : family.getRelation());
                    dataMap.put("workAddr" + count, family.getWorkAddr() == null ? "" : family.getWorkAddr());
                    dataMap.put("job" + count, family.getJob() == null ? " " : family.getJob());
                    dataMap.put("annualIncome" + count, family.getAnnualIncome() == null ? "" : family.getAnnualIncome());
                    dataMap.put("healthStatus" + count, family.getHealthStatus() == null ? "" : family.getHealthStatus());
                    count++;
                }
            }
            if (count < 7) {
                for (int i = count; i < 7; i++) {
                    dataMap.put("name" + i, "");
                    dataMap.put("age" + i, "");
                    dataMap.put("relation" + i, "");
                    dataMap.put("workAddr" + i, "");
                    dataMap.put("job" + i, " ");
                    dataMap.put("annualIncome" + i, "");
                    dataMap.put("healthStatus" + i, "");
                }
            }

//            dataMap.put("qrcode", QrUtil.crateQRCode("1234466", 100, 100));
            Configuration configuration = new Configuration(Configuration.getVersion());
            configuration.setDefaultEncoding("utf-8");
            Template template = freeMarkerConfigurer.getConfiguration().getTemplate("difficulty.ftl", "utf-8");
            Writer out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(),
                    StandardCharsets.UTF_8), 10240);
            response.setHeader("file-type", "msw");
            response.setHeader("msw-name", URLEncoder.encode("家庭经济困难学生认定申请表_" + difficultyApply.getStuName() + ".docx"));
//            response.setHeader("content-Type", "application/msword");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("家庭经济困难学生认定申请表_" + difficultyApply.getStuName() + ".docx", "utf-8"));
            response.setHeader("Access-Control-Expose-Headers", "file-type,msw-name");
            response.flushBuffer();
            template.process(dataMap, out);
            out.flush();
            out.close();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
    }

    private Object getParamValue(Object value) {
        return value == null ? "" : value;
    }
}
